<?php

namespace wchat\common;

use JetBrains\PhpStorm\ArrayShape;
use wchat\common\libs\Aliyun;
use wchat\common\libs\Qq;
use wchat\common\libs\Wx;

class AppConfig
{


    const int TYPE_WCHAT_PROJECT      = 0;
    const int TYPE_ALI_GAME_OR_APPLET = 3;
    const int TYPE_QQ_GAME_OR_APPLET  = 1;
    const int TYPE_APP_PROJECT        = 2;


    /**
     * @var string
     */
    public string $appId = '';


    /**
     * @var string
     */
    private string $host = '';

    /**
     * @var string
     */
    public string $appSecret = '';


    /**
     * @var PayConfig
     */
    public PayConfig $pay;


    private string $proxyHost   = '';
    private int    $proxyPort   = 0;
    private string $notifyUrl   = '';
    private string $body        = '';
    private string $currency    = 'CNY';
    private string $remoteIp    = '';
    private string $accessToken = '';
    private string $tradeType   = 'JSAPI';
    private string $signType    = 'MD5';

    /**
     * @var int
     */
    public int $type;


    /**
     * @var array|string[]
     */
    #[ArrayShape(['token' => 'string', 'secret' => 'string', 'unionId' => 'string'])]
    public array $notice = ['token' => '', 'secret' => '', 'unionId' => ''];


    public function __construct()
    {
        $this->pay      = new PayConfig();
        $this->pay->wx  = new Wx();
        $this->pay->qq  = new Qq();
        $this->pay->ali = new Aliyun();
    }


    /**
     * @param object $app
     * @return static
     */
    public static function instance(object $app): static
    {
        $model            = new static();
        $model->appId     = $app->appId;
        $model->appSecret = $app->appSecret;
        $model->type      = $app->type;

        PayConfig::parse($app->pay, $model->pay);

        return $model;
    }


    /**
     * @return bool
     */
    public function typeIsApp(): bool
    {
        return $this->type === self::TYPE_APP_PROJECT;
    }

    /**
     * @return string
     */
    public function getProxyHost(): string
    {
        return $this->proxyHost;
    }

    /**
     * @param string $proxyHost
     */
    public function setProxyHost(string $proxyHost): void
    {
        $this->proxyHost = $proxyHost;
    }

    /**
     * @return int
     */
    public function getProxyPort(): int
    {
        return $this->proxyPort;
    }

    /**
     * @param int $proxyPort
     */
    public function setProxyPort(int $proxyPort): void
    {
        $this->proxyPort = $proxyPort;
    }

    /**
     * @return string
     */
    public function getNotifyUrl(): string
    {
        return $this->notifyUrl;
    }

    /**
     * @param string $notifyUrl
     */
    public function setNotifyUrl(string $notifyUrl): void
    {
        $this->notifyUrl = $notifyUrl;
    }

    /**
     * @return string
     */
    public function getBody(): string
    {
        return $this->body;
    }

    /**
     * @param string $body
     */
    public function setBody(string $body): void
    {
        $this->body = $body;
    }

    /**
     * @return string
     */
    public function getCurrency(): string
    {
        return $this->currency;
    }

    /**
     * @param string $currency
     */
    public function setCurrency(string $currency): void
    {
        $this->currency = $currency;
    }

    /**
     * @return string
     */
    public function getRemoteIp(): string
    {
        return $this->remoteIp;
    }

    /**
     * @param string $remoteIp
     */
    public function setRemoteIp(string $remoteIp): void
    {
        $this->remoteIp = $remoteIp;
    }

    /**
     * @return string
     */
    public function getAccessToken(): string
    {
        return $this->accessToken;
    }

    /**
     * @param string $accessToken
     */
    public function setAccessToken(string $accessToken): void
    {
        $this->accessToken = $accessToken;
    }

    /**
     * @return string
     */
    public function getTradeType(): string
    {
        return $this->tradeType;
    }

    /**
     * @param string $tradeType
     */
    public function setTradeType(string $tradeType): void
    {
        $this->tradeType = $tradeType;
    }

    /**
     * @return string
     */
    public function getSignType(): string
    {
        return $this->signType;
    }

    /**
     * @param string $signType
     */
    public function setSignType(string $signType): void
    {
        $this->signType = $signType;
    }

    /**
     * @return string
     */
    public function getHost(): string
    {
        return $this->host;
    }

    /**
     * @param string $host
     */
    public function setHost(string $host): void
    {
        $this->host = $host;
    }

}